﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SQLite;
using System.Data;

namespace KProject.DAL
{
    static class CommonDAL
    {
        private static SQLiteConnection conn = new SQLiteConnection(@"Data Source=KProject.db");

        public static List<T> List<T>(SQLiteCommand cmd, Func<SQLiteDataReader, T> modelFunc)
        {
            List<T> itens = new List<T>();
            cmd.Connection = conn;
            SQLiteDataReader dr = null;

            try
            {
                conn.Open();
                dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);

                while (dr.Read())
                {
                    itens.Add(modelFunc(dr));
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (dr != null)
                    dr.Close();
                else
                    conn.Close();
            }

            return itens;
        }

        public static int ExecuteNonQuery(SQLiteCommand cmd)
        {
            int success;
            cmd.Connection = conn;

            try
            {
                conn.Open();
                success = cmd.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                conn.Close();
            }

            return success;
        }

        public static object ExecuteScalar(SQLiteCommand cmd)
        {
            object obj;
            cmd.Connection = conn;

            try
            {
                conn.Open();
                obj = cmd.ExecuteScalar();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                conn.Close();
            }

            return obj;
        }

        public static DataTable ExecuteDataTable(SQLiteCommand cmd)
        {
            DataTable dtt = new DataTable();
            cmd.Connection = conn;

            try
            {
                conn.Open();
                SQLiteDataAdapter dta = new SQLiteDataAdapter(cmd);
                dta.Fill(dtt);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                conn.Close();
            }

            return dtt;
        }

        public static void ExecuteTransaction(List<SQLiteCommand> cmds)
        {
            SQLiteTransaction transaction = null;

            try
            {
                conn.Open();
                transaction = conn.BeginTransaction();

                foreach (SQLiteCommand cmd in cmds)
                {
                    cmd.Connection = conn;
                    cmd.Transaction = transaction;
                    cmd.ExecuteNonQuery();
                }

                transaction.Commit();
            }
            catch (Exception ex)
            {
                if (transaction != null)
                    transaction.Rollback();
                throw ex;
            }
            finally
            {
                conn.Close();
            }
        }

        public static object ExecuteTransaction(List<SQLiteCommand> cmds, int index)
        {
            Object element = null;
            SQLiteTransaction transaction = null;

            try
            {
                conn.Open();
                transaction = conn.BeginTransaction();

                for (int i = 0; i < cmds.Count; i++)
                {
                    cmds[i].Connection = conn;
                    cmds[i].Transaction = transaction;

                    if (i == index)
                        element = cmds[i].ExecuteScalar();
                    else
                        cmds[i].ExecuteNonQuery();
                }
                
                transaction.Commit();
            }
            catch (Exception ex)
            {
                if (transaction != null)
                    transaction.Rollback();
                throw ex;
            }
            finally
            {
                conn.Close();
            }

            return element;
        }
    }
}
